﻿using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;

namespace Plugins.Engine
{
    [Serializable]
    public class PluginPriorityItem<T> : IEquatable<PluginPriorityItem<T>>, IComparable<PluginPriorityItem<T>>
    {
        private readonly T _item;
        private int _priority;
        public PluginPriorityItem(int priority, T item)
        {
            _priority = priority;
            _item = item;
        }
        public T Item { get { return _item; } }
        public int Priority { get { return _priority; } set { _priority = value; } }
        #region IComparable<PriorityItem<T>> Members
        public int CompareTo(PluginPriorityItem<T> other)
        {
            if (!object.Equals(other, null))
            {
                return _priority - other._priority;
            }
            return 0;
        }
        [SuppressMessage("Microsoft.Naming", "CA1704")]
        public static bool operator !=(PluginPriorityItem<T> a, PluginPriorityItem<T> b)
        {
            if (!object.Equals(a, null) && !object.Equals(b, null))
            {
                return !a.Equals(b);
            }
            return false;
        }
        [SuppressMessage("Microsoft.Naming", "CA1704")]
        public static bool operator ==(PluginPriorityItem<T> a, PluginPriorityItem<T> b)
        {
            if (!object.Equals(a, null) && !object.Equals(b, null))
            {
                return a.Equals(b);
            }
            return false;
        }
        [SuppressMessage("Microsoft.Naming", "CA1704")]
        public static bool operator <(PluginPriorityItem<T> a, PluginPriorityItem<T> b)
        {
            if (!object.Equals(a, null) && !object.Equals(b, null))
            {
                return a.CompareTo(b) < 0;
            }
            return false;
        }
        [SuppressMessage("Microsoft.Naming", "CA1704")]
        public static bool operator >(PluginPriorityItem<T> a, PluginPriorityItem<T> b)
        {
            if (!object.Equals(a, null) && !object.Equals(b, null))
            {
                return a.CompareTo(b) > 0;
            }
            return false;
        }
        #endregion
        #region IEquatable<PriorityItem<T>> Members
        public bool Equals(PluginPriorityItem<T> other)
        {
            if (other != null)
            {
                if (_priority == other._priority)
                {
                    IEquatable<T> a = _item as IEquatable<T>;
                    T b = other._item;
                    if (a != null && b != null)
                    {
                        return a.Equals(b);
                    }
                    return Equals(_item, other._item);
                }
            }
            return false;
        }
        #endregion
        public override string ToString()
        {
            return string.Format(CultureInfo.InvariantCulture, "[priority={0}, item={1}]", _priority, _item);
        }
        public override bool Equals(object obj)
        {
            PluginPriorityItem<T> item = obj as PluginPriorityItem<T>;
            if (item != null)
            {
                return this.Equals(item);
            }
            return base.Equals(obj);
        }
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
}
